package level4.assets
{
	import flash.display.Loader;
	import flash.system.ApplicationDomain;
	import flash.utils.describeType;
	import flash.utils.getDefinitionByName;
	
	import level4.helpers.ReflectHelper;
	import level4.interfaces.dispose.IDisposable;

	/**
	 * 管理游戏用到的资源,
	 * 思想: 以swf的url作为key,分别将Loader保存进allLoaderObj,
	 * loader的ApplicationDomain保存进allDomainObj
	 * 功能:
	 * 1. 相同的swf(ApplicationDomain),只加载一次
	 * */
	public class AssetsManager
	{
		/**
		 * 存放所有的 域
		 * */
		private static var allDomainObj:Object = {};
		/**
		 * 存放所有的Loader,为了unload的操作
		 * */
		private static var allLoaderObj:Object = {};
		
		/**
		 * 卸载载入的所有资源
		 * **/
		public static function disposeAll(gc:Boolean=false):void{
			var key:String = null;
			//allDomainObj
			for(key in allDomainObj){
				allDomainObj[key] = null;
				delete allDomainObj[key];
			}
			//allLoaderObj
			for(key in allLoaderObj){
				allLoaderObj[key].unloadAndStop(gc);
				delete allLoaderObj[key];
			}
			
		} 
		/**
		 * 卸载一个 swf
		 * */
		public static function disposeOne(key:String,gc:Boolean=false):void{
			if(key){
				allDomainObj[key] = null;
				delete allDomainObj[key];
				allLoaderObj[key].unloadAndStop(gc);
				delete allLoaderObj[key];
			}
		}
		
		/**
		 * 一次性加载urls中所有的swf.
		 * 
		 * @urls ,swf的地址
		 * @beforeLoadFun,加载之前将调用beforeLoadFun.
		 * @loadedCompleteFun,加载完毕后将调用loadedCompleteFun.
		 * */
		public static function loadSwfs(urls:Array,beforeLoadFun:Function,loadedCompleteFun:Function):void{
			if(urls){
				var url:String;
				var loadedCount:int = 0;
				if(beforeLoadFun !=null)
					beforeLoadFun();
				
				for each(url in urls){
					if(!allDomainObj[url]){
						ReflectHelper.loadExportedThatApplicationDomain(url,function(domain:ApplicationDomain,...args):void{
							allDomainObj[args[0]] = domain;
							
							loadedCount ++;
							if(loadedCount == urls.length && loadedCompleteFun != null){
								loadedCompleteFun();
							}
						},null,url);
					}else{
						loadedCount ++;
						if(loadedCount == urls.length  && loadedCompleteFun != null){
							loadedCompleteFun();
						}
					}
				}
				
			}
		}
		
		/**
		 * 从全部域中,获取类
		 * */
		public static function getClassFromAllAssets(name:String):Class{
			try{
				return getDefinitionByName(name) as Class;
			}catch(e:Error){
				for(var key:String in allDomainObj){
					try{
						var domain:ApplicationDomain = allDomainObj[key];
						return domain.getDefinition(name) as Class;
					}catch(err:Error){}
				}
			}
			throw new Error("所有域,没有找到类:{"+name+"}");
		}
		/**
		 * 从指定 域中,获取Class
		 * */
		public static function getClassFromAsset(assetUrlKey:String,className:String):Class{
			if(assetUrlKey){
				return allDomainObj[assetUrlKey].getDefinition(className) as Class;
			}
			throw new Error("域,["+assetUrlKey+"]中未找到类:{"+className+"}");
		}
		
		/**
		 * 保存一个 Loader
		 * 如果有冲突的Loader,则卸载旧的,保存新的
		 * */
		public static function addOneLoader(key:String,value:Loader):void{
			if(key){
				if(allLoaderObj[key] != null)
					allLoaderObj[key].unload();
				if(value)
					allLoaderObj[key] = value;
				if(value.contentLoaderInfo.applicationDomain)
					allDomainObj[key] = value.contentLoaderInfo.applicationDomain;
			}
		}
		
		////////////////////////////////
		//Getter
		////////////////////////////////
		/**
		 * 获取 所持有的 所有的域
		 * */
		public static function get AllDomainObj():Object{
			return allDomainObj;
		}
		/**
		 * 获取 所有域的key
		 * */
		public static function get AllDomainKeys():Array{
			var keys:Array = [];
			var key:String = null;
			for(key in allDomainObj){
				if(key != null && key != ""){
					keys.push(key);
				}
			}
			return keys;
		}
		
	}
}